/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package saludfamiliar;

import geografia.GestorLocalidad;
import geografia.Localidad;
import geografia.Provincia;
import hibernate.GestorHibernate;
import java.io.IOException;
import java.util.*;
import jxl.Sheet;
import modelo.patologias.Enfermedad;
import modelo.patologias.GestorEnfermedad;
import modelo.patologias.Sintoma;
import modelo.patologias.TipoEnfermedad;
import modelo.personas.Telefono;
import modelo.personas.pacientes.GestorPaciente;
import modelo.personas.pacientes.Paciente;
import modelo.personas.profesionales.Especialidad;
import modelo.personas.profesionales.GestorProfesional;
import modelo.personas.profesionales.Profesional;
import prolog.GestorPrologEnfermedad;
import prolog.GestorPrologPaciente;
import util.Bolillero;
import util.BolilleroConExtraccion;
import util.Formateador;
import util.GestorExcel;

/**
 *
 * @author raul
 */
public class CreadorObjetos {
    
    private GestorHibernate gestor = new GestorHibernate();

    private GestorExcel libro = new GestorExcel(
            getClass().getResource("/saludfamiliar/Datos.xls").getPath());
    
    private List<Sintoma> sintomas;
    private Bolillero bol;
    
    private int mat = 0;
    
    public CreadorObjetos() {
        try {
            libro.abrir();
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

    public void crearProvincias(){
        Sheet hoja = libro.getHoja("Provincias");
        for (int i=0; i<hoja.getRows();i++){
            gestor.guardarObjeto(new Provincia(hoja.getCell(0, i).getContents()));
        }
    }
    
    public void crearLocalidades(){
        GestorLocalidad gestorL = new GestorLocalidad();
        HashMap<String, Provincia> provincias = new HashMap<String, Provincia>();
        Iterator<Provincia> it = gestorL.listarProvincias().iterator();
        while(it.hasNext()){
            Provincia p = it.next();
            provincias.put(p.toString(), p);
        }

        Sheet hoja = libro.getHoja("Localidades");            
        for (int i=0; i<hoja.getRows();i++){
            gestorL.guardarObjeto(new Localidad(Integer.parseInt(hoja.getCell(0, i).getContents()),
                    Formateador.toCamelCase(hoja.getCell(1, i).getContents()),
                    provincias.get(hoja.getCell(2, i).getContents()))
                    );
        }
    }
    
    public void crearEspecialidades(){
        Sheet hoja = libro.getHoja("Especialidades");
        for (int i=0; i<hoja.getRows();i++){
            gestor.guardarObjeto(new Especialidad(Formateador.toCamelCase(hoja.getCell(0, i).getContents()),
                    hoja.getCell(1, i).getContents()));
        }
    }
    
    public void crearSintomas() {
        Sheet hoja = libro.getHoja("Sintomas");
        for (int i=0; i<hoja.getRows();i++){
            gestor.guardarObjeto(new Sintoma(Formateador.toCamelCase(hoja.getCell(0, i).getContents()), null));
        }
        
    }
    
    public void crearEnfermedades(){//Alta recursividad en este metodo
        sintomas = (new GestorEnfermedad()).listarSintomas();
        bol = new Bolillero();
        crearTipoEnfermedad(0, 4, null);
        
    }
    
    private void crearTipo(String nombre, String descripcion, TipoEnfermedad supertipo, int pT, int uT, int pE, int uE) {
        TipoEnfermedad tipoenfermedad = new TipoEnfermedad(nombre, descripcion, supertipo);
        gestor.guardarObjeto(tipoenfermedad);
        crearTipoEnfermedad(pT, uT, tipoenfermedad); //crear subtipos de tipoenfermedad
        //crear enfermedades de tipo = tipoenfermedad
        Sheet hoja2 = libro.getHoja("Enfermedades");
        for (int j= pE; j<uE; j++){
            gestor.guardarObjeto(new Enfermedad(Formateador.toCamelCase(hoja2.getCell(0, j).getContents()),
                    hoja2.getCell(1, j).getContents(),
                    tipoenfermedad,
                    obtenerSintomas(bol.aleatorioEntre(2, 7)))); 
        }
    }

    //pT es el indice del primer subtipo del tipo
    private void crearTipoEnfermedad(int pT, int uT, TipoEnfermedad supertipo) throws NumberFormatException {
        Sheet hoja = libro.getHoja("TiposEnfermedad");
        for (int i= pT ; i<uT ; i++){
            crearTipo(Formateador.toCamelCase(hoja.getCell(0, i).getContents()),
                    hoja.getCell(5, i).getContents(),
                    supertipo,
                    Integer.parseInt(hoja.getCell(1, i).getContents()),
                    Integer.parseInt(hoja.getCell(2, i).getContents()),
                    Integer.parseInt(hoja.getCell(3, i).getContents()),
                    Integer.parseInt(hoja.getCell(4, i).getContents())
                    );
        }
    }
    
    private Set<Sintoma> obtenerSintomas(int cantidad){
        BolilleroConExtraccion bolCE = new BolilleroConExtraccion(0, sintomas.size()-1);
        HashSet<Sintoma> sint = new HashSet<Sintoma>();
        for (int i=0;i<cantidad;i++) {
            bolCE.sortear();
            sint.add(sintomas.get(bolCE.getValor()));
        }
        return sint;
    }
    
    public void cargarPacientes() {
        Sheet hoja = libro.getHoja("Pacientes");
        bol = new Bolillero();
        GestorPaciente gp = new GestorPaciente();
        List localidades = (new GestorLocalidad()).listarLocalidades();
        for (int i=0; i<hoja.getRows();i++){
            gp.crearModelo();
            Paciente pac = gp.getModelo();
            pac.setNombre(Formateador.toCamelCase(hoja.getCell(0, i).getContents()));
            pac.setApellido(Formateador.toCamelCase(hoja.getCell(1, i).getContents()));
            pac.setSexo(Formateador.toCamelCase(hoja.getCell(2, i).getContents()));
            pac.setFechaNacimiento(fechaAleatoria());
            pac.setEmail(crearEmail(pac.getNombre(),pac.getApellido()));
            pac.getTelefonos().add(
                    (Telefono) gp.nuevoTelefono("0"+bol.aleatorioEntre(1111, 9999),
                       bol.aleatorioEntre(111111, 999999999)));
            if (0==bol.aleatorioEntre(0, 1)){
                pac.getTelefonos().add(
                    (Telefono) gp.nuevoTelefono("0"+bol.aleatorioEntre(1111, 9999),
                       bol.aleatorioEntre(111111, 999999999)));
            }
            gp.setDomicilio(Formateador.toCamelCase(hoja.getCell(4, i).getContents()),
                bol.aleatorioEntre(1, 2000), -1, "", "", localidadAleatoria(localidades));
            gp.setDocumento("DNI", Integer.parseInt(hoja.getCell(3, i).getContents()));
            pac.setFechaAlta(new Date());
            gp.guardar();
        }
    }

    private Date fechaAleatoria() {
        Calendar fecha = Calendar.getInstance();
        fecha.set(bol.aleatorioEntre(1930, 2003),
                bol.aleatorioEntre(0, 11), bol.aleatorioEntre(1, 28));
        return fecha.getTime();
    }

    private String crearEmail(String nombre, String apellido) {
        String [] dominios = {"@gmail.com","@yahoo.com","@hotmail.com","@fibertel.com","@live.com", "@arnet.com"};
        return nombre.toLowerCase().charAt(0) + apellido.toLowerCase() + dominios[bol.aleatorioEntre(0, 5)];
    }

    private Localidad localidadAleatoria(List localidades) {
        return (Localidad) localidades.get(bol.aleatorioEntre(0, localidades.size()-1));
    }
    
    public void cargarProfesionales(){
        Sheet hoja = libro.getHoja("Profesionales");
        bol = new Bolillero();
        GestorProfesional gp = new GestorProfesional();
        List localidades = (new GestorLocalidad()).listarLocalidades();
        List especialidades = gp.listarEspecialidades();
        for (int i=0; i<hoja.getRows();i++){
            gp.crearModelo();
            Profesional pac = gp.getModelo();
            pac.setNombre(Formateador.toCamelCase(hoja.getCell(0, i).getContents()));
            pac.setApellido(Formateador.toCamelCase(hoja.getCell(1, i).getContents()));
            pac.setSexo(Formateador.toCamelCase(hoja.getCell(2, i).getContents()));
            pac.setFechaNacimiento(fechaAleatoria());
            pac.setEmail(hoja.getCell(4, i).getContents());
            pac.getTelefonos().add(
                    (Telefono) gp.nuevoTelefono("0"+bol.aleatorioEntre(1111, 9999),
                       bol.aleatorioEntre(111111, 999999999)));
            if (0==bol.aleatorioEntre(0, 1)){
                pac.getTelefonos().add(
                    (Telefono) gp.nuevoTelefono("0"+bol.aleatorioEntre(1111, 9999),
                       bol.aleatorioEntre(111111, 999999999)));
            }
            gp.setDomicilio(Formateador.toCamelCase(hoja.getCell(3, i).getContents()),
                bol.aleatorioEntre(1, 2000), -1, "", "", localidadAleatoria(localidades));
            gp.setDocumento("DNI", bol.aleatorioEntre(11111111, 49999999));
            pac.setFechaAlta(new Date());
            pac.setMatricula(matriculaAleatoria());
            pac.setEspecialidades(especialidadesAleatorias(especialidades));
            gp.guardar();
        }
    }

    private String matriculaAleatoria() {
        String word ="qwertyuiopasdfghjklñzxcvbnm";
        return word.charAt(bol.aleatorioEntre(0, 26)) +String.format("%03d", mat++);
    }

    private Set<Especialidad> especialidadesAleatorias(List especialidades) {
        HashSet<Especialidad> result = new HashSet<>();
        BolilleroConExtraccion bolCE = new BolilleroConExtraccion(0, especialidades.size());
        int [] cants = {1,1,1,2,2,3};
        int cant = cants[bol.aleatorioEntre(0, 5)];
        for (int i = 0; i<cant; i++){
            bolCE.sortear();
            result.add((Especialidad) especialidades.get(bolCE.getValor()));
        }
        return result;
    }
    
    public void actualizarBaseDeConocimiento(){
        GestorPrologEnfermedad gpe = new GestorPrologEnfermedad();
        Iterator i = (new GestorEnfermedad()).listarEnfermedades().iterator();
        while (i.hasNext()) {            
            gpe.actualizarInfoEnfermedad((Enfermedad)i.next());
        }
        GestorPrologPaciente gpp = new GestorPrologPaciente();
        Iterator j = (new GestorPaciente()).listarPacientes().iterator();
        while (j.hasNext()) {            
            Paciente p = (Paciente) j.next();
            gpp.actualizarInfoPaciente(p);
            gpp.actualizarEnfermedadesPaciente(p);
        }
    }
}
